// pages/scanQR/scanQR.js
const base64 = require("../../utils/base64")
const app = getApp();
Page({

    /**
     * 页面的初始数据
     */
    data: {
       show_img: 'yes',
       ip: '',
       show_res: '',
       imageBase64Str: '',
       location: '',
       qrImageSrc: '',
       baiduToken: '',
       recognizeType: 'qr_code', // 默认识别二维码
       recognizeTypes: [
         {id: 'qr_code', name: '二维码/条形码'},
         {id: 'license_plate', name: '车牌'},
         {id: 'ticket', name: '车票'},
         {id: 'receipt', name: '购物小票'},
         {id: 'face', name: '人脸'},
         {id: 'voice', name: '语音'}
       ],
       // 语音识别相关
       isRecording: false,
       recordingFilePath: ''
    },
    // 1.获取百度大脑接口Token
    getBaiduToken() {
      let apikey = 'X4Q1wZdtVIeZZM9dceRHBASF'  //百度大脑API
      let seckey = 'JLM2QKFdlZ2NPnoFR2kmzVtvI1CImHCy'  //百度大脑API
      let tokenUrl = `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${apikey}&client_secret=${seckey}`
      let that = this
      
      return new Promise((resolve, reject) => {
        wx.request({
          url: tokenUrl,
          method: 'POST',
          dataType: 'json',
          header: {
              'content-type': 'application/x-www-form-urlencoded'
          },
          success(res) {
              console.log('百度大脑接口获取成功', res);
              if (res.data && res.data.access_token) {
                that.setData({
                  baiduToken: res.data.access_token
                });
                resolve(res.data.access_token);
              } else {
                reject('获取Token失败');
              }
          },fail(res) {
              console.log('接口获取失败', res);
              reject('网络请求失败');
          }
        })
      });
    },
    
    // 2.选择图片进行识别
    selectImage() {
      let that = this
      return new Promise(function (resolve, reject) {
        wx.chooseMedia({
          count: 1,
          mediaType: ['image'],
          sourceType: ['album', 'camera'],
          success(res) {
              console.log('选择图片', res);
              that.setData({
                  qrImageSrc: res.tempFiles[0].tempFilePath
              })
              // 读取图片并转换为base64
              wx.getFileSystemManager().readFile({
                  filePath: res.tempFiles[0].tempFilePath,
                  encoding: 'base64',
                  success: resolve,
                  fail: reject
              })
          },
          fail: reject
        })
      })
    },
    
    // 3.根据选择的类型进行识别
    recognizeImage(type) {
      let that = this;
      
      that.setData({
        recognizeType: type,
        show_res: '',
        location: '',
        qrImageSrc: ''
      });
      
      wx.showLoading({
        title: '准备识别...',
      });
      
      if (type === 'voice') {
        // 语音识别
        wx.hideLoading();
        that.startVoiceRecognition();
      } else if (type === 'qr_code') {
        // 二维码识别使用微信原生API
        wx.hideLoading();
        that.queryIp();
      } else {
        // 图片相关识别（人脸、车牌、车票、购物小票）
        // 先获取Token，再选择图片进行识别
        that.getBaiduToken().then(() => {
          that.selectImage().then(res => {
            wx.hideLoading();
            
            if (type === 'face') {
              // 人脸识别
              that.faceRecognition(res.data);
            } else {
              // 其他类型使用百度大脑API
              that.scanImageInfo(res.data, type);
            }
          }).catch(err => {
            wx.hideLoading();
            wx.showToast({
              title: '选择图片失败',
              icon: 'none'
            });
            console.error('选择图片失败', err);
          });
        }).catch(err => {
          wx.hideLoading();
          wx.showToast({
            title: '获取百度大脑Token失败',
            icon: 'none'
          });
          console.error('获取Token失败', err);
        });
      }
    },
    
    // 6.人脸识别功能
    faceRecognition(imageData) {
      let that = this;
      let detectUrl = `https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=${that.data.baiduToken}`;
      
      wx.showLoading({
        title: '正在识别人脸...',
      })
      
      wx.request({
        url: detectUrl,
        data: {
          image: imageData,
          image_type: 'BASE64',
          face_field: 'age,beauty,expression,faceshape,gender,glasses,landmark,race,quality,eye_status,emotion,face_type'
        },
        method: 'POST',
        dataType: 'json',
        header: {
          'content-Type': 'application/json'
        },
        success(res) {
          wx.hideLoading();
          console.log('人脸识别成功', res);
          
          let resultText = '人脸识别结果：\r\n\r\n';
          
          if (res.data.error_code === 0 && res.data.result && res.data.result.face_num > 0) {
            const faceInfo = res.data.result.face_list[0];
            resultText += `检测到人脸数：${res.data.result.face_num}\r\n`;
            resultText += `\r\n人脸1信息：\r\n`;
            resultText += `年龄：${faceInfo.age}岁\r\n`;
            resultText += `性别：${faceInfo.gender.type === 'male' ? '男' : '女'} (置信度：${faceInfo.gender.probability.toFixed(2)})\r\n`;
            resultText += `颜值：${faceInfo.beauty.toFixed(1)}分\r\n`;
            resultText += `表情：${faceInfo.expression.type === 0 ? '无表情' : faceInfo.expression.type === 1 ? '微笑' : '大笑'} (置信度：${faceInfo.expression.probability.toFixed(2)})\r\n`;
            resultText += `是否戴眼镜：${faceInfo.glasses.type === 0 ? '无眼镜' : faceInfo.glasses.type === 1 ? '普通眼镜' : '墨镜'} (置信度：${faceInfo.glasses.probability.toFixed(2)})\r\n`;
            resultText += `情绪：${that.getEmotionText(faceInfo.emotion.type)} (置信度：${faceInfo.emotion.probability.toFixed(2)})\r\n`;
            resultText += `脸型：${that.getFaceShapeText(faceInfo.faceshape.type)} (置信度：${faceInfo.faceshape.probability.toFixed(2)})\r\n`;
            resultText += `人种：${that.getRaceText(faceInfo.race.type)} (置信度：${faceInfo.race.probability.toFixed(2)})`;
          } else {
            resultText += '未识别到人脸或识别失败\r\n';
            resultText += `错误信息：${res.data.error_msg || '未知错误'}`;
          }
          
          that.setData({
            show_res: 'yes',
            show_img: '',
            location: resultText
          })
        }, 
        fail (res) {
          wx.hideLoading();
          console.log('请求失败', res);
          that.setData({
            show_res: 'yes',
            show_img: '',
            location: '识别失败：\r\n' + (res.errMsg || '未知错误')
          })
        }
      })
    },
    
    // 7.语音识别功能 - 开始录音
    startVoiceRecognition() {
      let that = this;
      
      that.setData({
        isRecording: true
      });
      
      wx.showToast({
        title: '请开始说话...',
        icon: 'none'
      });
      
      const recorderManager = wx.getRecorderManager();
      
      recorderManager.onStart(() => {
        console.log('录音开始');
        wx.showToast({
          title: '正在录音...',
          icon: 'none'
        });
      });
      
      recorderManager.onStop((res) => {
        console.log('录音停止', res);
        that.setData({
          isRecording: false,
          recordingFilePath: res.tempFilePath
        });
        that.processVoiceRecognition(res.tempFilePath);
      });
      
      const options = {
        duration: 60000, // 最长录音时间60秒
        sampleRate: 16000,
        numberOfChannels: 1,
        encodeBitRate: 96000,
        format: 'wav',
        frameSize: 50
      };
      
      recorderManager.start(options);
      
      // 显示录音提示框，提供停止按钮
      wx.showModal({
        title: '语音识别',
        content: '正在录音，请说话...',
        showCancel: true,
        cancelText: '停止录音',
        confirmText: '取消',
        success(res) {
          if (res.cancel) {
            // 用户点击停止录音
            recorderManager.stop();
          } else {
            // 用户点击取消
            recorderManager.stop();
          }
        }
      });
    },
    
    // 8.处理语音识别结果
    processVoiceRecognition(filePath) {
      let that = this;
      
      wx.showLoading({
        title: '正在识别语音...',
      });
      
      // 先获取Token，再进行语音识别
      that.getBaiduToken().then(() => {
        // 读取音频文件并转换为base64
        wx.getFileSystemManager().readFile({
          filePath: filePath,
          encoding: 'base64',
          success: (res) => {
            that.voiceRecognition(res.data);
          },
          fail: (err) => {
            wx.hideLoading();
            console.error('读取音频文件失败', err);
            that.setData({
              show_res: 'yes',
              show_img: '',
              location: '语音识别失败：\r\n读取音频文件失败'
            });
          }
        });
      }).catch(err => {
        wx.hideLoading();
        wx.showToast({
          title: '获取百度大脑Token失败',
          icon: 'none'
        });
        console.error('获取Token失败', err);
        that.setData({
          show_res: 'yes',
          show_img: '',
          location: '语音识别失败：\r\n获取Token失败'
        });
      });
    },
    
    // 9.语音识别API调用
    voiceRecognition(audioBase64) {
      let that = this;
      let detectUrl = `https://aip.baidubce.com/rest/2.0/speech/v1/recognize?access_token=${that.data.baiduToken}`;
      
      wx.request({
        url: detectUrl,
        data: {
          format: 'wav',
          rate: 16000,
          channel: 1,
          cuid: 'miniprogram',
          token: that.data.baiduToken,
          speech: audioBase64,
          len: audioBase64.length
        },
        method: 'POST',
        dataType: 'json',
        header: {
          'content-Type': 'application/json'
        },
        success(res) {
          wx.hideLoading();
          console.log('语音识别成功', res);
          
          let resultText = '语音识别结果：\r\n\r\n';
          
          if (res.data.err_no === 0 && res.data.result && res.data.result.length > 0) {
            resultText += `识别文本：${res.data.result[0]}\r\n\r\n`;
            resultText += '提示：请核对识别结果，可能存在误差';
          } else {
            resultText += '语音识别失败\r\n';
            resultText += `错误信息：${res.data.err_msg || '未知错误'}`;
          }
          
          that.setData({
            show_res: 'yes',
            show_img: '',
            location: resultText
          })
        }, 
        fail (res) {
          wx.hideLoading();
          console.log('请求失败', res);
          that.setData({
            show_res: 'yes',
            show_img: '',
            location: '语音识别失败：\r\n' + (res.errMsg || '未知错误')
          })
        }
      })
    },
    
    // 辅助函数：获取情绪文本
    getEmotionText(type) {
      const emotions = {
        0: '无情绪',
        1: '愤怒',
        2: '厌恶',
        3: '恐惧',
        4: '高兴',
        5: '伤心',
        6: '惊讶'
      };
      return emotions[type] || '未知';
    },
    
    // 辅助函数：获取脸型文本
    getFaceShapeText(type) {
      const shapes = {
        'square': '方形',
        'triangle': '三角形',
        'oval': '椭圆形',
        'heart': '心形',
        'round': '圆形'
      };
      return shapes[type] || '未知';
    },
    
    // 辅助函数：获取人种文本
    getRaceText(type) {
      const races = {
        'yellow': '黄种人',
        'white': '白种人',
        'black': '黑种人',
        'arabs': '阿拉伯人'
      };
      return races[type] || '未知';
    },
    
    // 4.二维码/条形码识别（微信原生API）
    queryIp() {
        let that = this
        // 允许从相机和相册扫码
        wx.scanCode({
          success (res) {
            console.log(res)
            let result = ""
            if (res.result == "*" || res.result == "") {
                result = "解码后的内容是：" + base64.decode(res.rawData)
            } else {
                result = "解码后的内容是：" + res.result
            }
            result += "\r\n\n[数据类型]：" + res.scanType
            if (res.scanType == "QR_CODE" || res.scanType == "DATA_MATRIX" || res.scanType == "PDF_417") {
                result = result + "二维码"
            } else if (res.scanType == "WX_CODE") {
                result = result + "小程序码"
            } else {
                result += "一维码"
            }
            result += "\r\n\n[字符集]：" + res.charSet
            if (res.path != "undefine" && res.path != "" && res.path != null ) {
                result += "\r\n\n[path]:" + res.path
            }
            
            that.setData({
                show_res: 'yes',
                show_img: '',
                location: result
            })
          },fail(res) {
              wx.showToast({
                title: '无法识别',
                icon: 'none'
              })
              that.setData({
                  show_res: 'yes',
                  show_img: '',
                  location: '识别错误： \r\n' + res.errMsg
              })
          }
        })
    },
    
    // 5.使用百度大脑API进行图片识别
    scanImageInfo(imageData, type) {
        let that = this;
        let detectUrl = '';
        let resultTitle = '';
        
        // 根据识别类型选择不同的API接口
        switch(type) {
          case 'license_plate':
            detectUrl = `https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=${that.data.baiduToken}`;
            resultTitle = '车牌识别结果';
            break;
          case 'ticket':
            detectUrl = `https://aip.baidubce.com/rest/2.0/ocr/v1/train_ticket?access_token=${that.data.baiduToken}`;
            resultTitle = '车票识别结果';
            break;
          case 'receipt':
            detectUrl = `https://aip.baidubce.com/rest/2.0/ocr/v1/receipt?access_token=${that.data.baiduToken}`;
            resultTitle = '购物小票识别结果';
            break;
          default:
            detectUrl = `https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=${that.data.baiduToken}`;
            resultTitle = '通用文字识别结果';
        }
        
        wx.showLoading({
          title: '正在识别...',
        })
        
        wx.request({
          url: detectUrl,
          data: {
              image: imageData
          },
          method: 'POST',
          dataType: 'json',
          header: {
              'content-Type': 'application/x-www-form-urlencoded'
          },
          success(res) {
              wx.hideLoading();
              console.log('识别成功', res);
              
              let resultText = resultTitle + "：\r\n\r\n";
              
              // 根据不同类型解析识别结果
              if (type === 'license_plate' && res.data.words_result) {
                // 车牌识别结果解析
                const plateInfo = res.data.words_result;
                resultText += `车牌号：${plateInfo.number || '未知'}\r\n`;
                resultText += `颜色：${plateInfo.color || '未知'}\r\n`;
                resultText += `置信度：${(plateInfo.confidence * 100).toFixed(2)}%`;
              } else if ((type === 'ticket' || type === 'receipt') && res.data.words_result) {
                // 车票或小票识别结果解析
                res.data.words_result.forEach((item, index) => {
                  resultText += `${item.words}\r\n`;
                });
              } else if (res.data.words_result) {
                // 通用文字识别结果解析
                res.data.words_result.forEach((item, index) => {
                  resultText += `${item.words}\r\n`;
                });
              } else {
                resultText += '未识别到有效内容';
              }
              
              that.setData({
                show_res: 'yes',
                show_img: '',
                location: resultText
              })
          }, 
          fail (res) {
              wx.hideLoading();
              console.log('请求失败', res.data);
              that.setData({
                show_res: 'yes',
                show_img: '',
                location: '识别失败：\r\n' + (res.errMsg || '未知错误')
              })
          }
        })
    },
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad(options) {
      // 检查是否有传递过来的扫码结果
      if (options && options.result) {
        // 解码URL编码的结果
        const result = decodeURIComponent(options.result);
        this.setData({
          show_res: 'yes',
          show_img: '',
          location: result
        });
      }
    },
    
    /**
     * 复制结果到剪贴板
     */
    copyBtn() {
      wx.setClipboardData({
        data: this.data.location,
        success: () => {
          wx.showToast({
            title: '复制成功',
            icon: 'success'
          })
        }
      })
    },
    
    /**
     * 重新识别
     */
    scanAgain() {
      this.setData({
        show_res: '',
        show_img: 'yes',
        location: '',
        qrImageSrc: '',
        isRecording: false,
        recordingFilePath: ''
      });
      
      // 根据当前选择的识别类型进行重新识别
      if (this.data.recognizeType === 'voice') {
        this.startVoiceRecognition();
      } else if (this.data.recognizeType === 'qr_code') {
        this.queryIp();
      } else {
        this.recognizeImage(this.data.recognizeType);
      }
    }
    
    // 其他生命周期函数保持默认
})